package us.icitap.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import us.icitap.utils.Result;

public class PersistenceFacade implements IPersistenceFacade {




	@Override
	public <T> Result<T> saveEntity(T entity, EntityManager em){
		try {
			T object = em.merge(entity);
			return new Result<T>(object, true, null);
		} catch (Exception e) {
			return new Result<T>(null, false, e.getMessage());
		}
	}
	
	@Override
	public <T> Result<List<T>> getList(Class<T> entityClass, boolean withStatus, String orderBy, EntityManager em){
		
		try {
			List<T> list = getListFromDB( entityClass,  withStatus,  orderBy, em);
			return new Result<List<T>>(list, true, null);
		} catch (Exception e) {
			e.printStackTrace();
			return new Result<List<T>>(null, false, e.getMessage());
		}
		
		
		
	}

	private <T> List<T> getListFromDB(Class<T> entityClass, boolean withStatus, String orderBy, EntityManager em) {
		
			String sql = "Select o from " + entityClass.getSimpleName() + " o";
			if (withStatus) {
				sql += " where o.status = :status ";
				return em.createQuery(sql).setParameter("status", true).getResultList();
			}

			if(orderBy != null)
				sql += " order by " + orderBy + " DESC";
			return em.createQuery(sql).getResultList();

		
	}
	


	@Override
	@SuppressWarnings("unchecked")
	public <T> Result<List<T>> findByCriteria(List<Expression> expressions,String groupByFields, String sortFields, Class<T> entity, EntityManager em) {

		try {
			Query query = QueryBuilder.createQuery(em, expressions,
					groupByFields, sortFields, entity.getSimpleName());
			List<T> listT = query.setMaxResults(500).getResultList();
			
			return new Result<List<T>>(listT, true, null);
		} catch (Exception e) {
			return new Result<List<T>>(null, false, e.getMessage());
		}
	}
	


	
	@Override
	public <T> Result<T> findEntityById(Object id, Class<T> entity, EntityManager em) {
		try {

			
			T obj = em.find(entity, id);
			
			return new Result<T>(obj, true, null);
		} catch (Exception e) {
			return new Result<T>(null, false, e.getMessage());
		}

	}
}
